
# $Id$
#
#  UMKC Robotics 2009.
#


#################################################################
# our compiler and other avr tools.
AVR_HOME = /opt/avr
CC = avr-gcc
NM = avr-nm
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRDUDE = avrdude
FORMAT = ihex
.PHONY: clean setdeps

# MCU name
MCU_TARGET = atmega128

# Processor frequency.  (This is from the 07-08 Makefile).
#     This will define a symbol, F_CPU, in all source code files equal to the 
#     processor frequency. You can then use this symbol in your source code to 
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
F_CPU = 16000000


#################################################################
# names for elf output files.  These are not targets. PRG_ROBOT will change
# depending on which module you compile. (see below). 
PRG_ROBOT = robot09
PRG_CORE = $(PRG_ROBOT)_core
PRG_NAVIGATION = $(PRG_ROBOT)_navigation
PRG_RUNTIME = $(PRG_ROBOT)_runtime


#################################################################
#  Sources and Object Files.
#
SRC_HWABSTRACTION = hwabstraction.c 
OBJ_HWABSTRACTION = hwabstraction.o
SRC_INPUT_CONTROLLER = input_controller.c 
OBJ_INPUT_CONTROLLER = input_controller.o
SRC_OUTPUT_CONTROLLER = output_controller.c 
OBJ_OUTPUT_CONTROLLER = output_controller.o
SRC_2D = 2d.c 
OBJ_2D = 2d.o
SRC_MOTORS = motors.c 
OBJ_MOTORS = motors.o
SRC_LIGHT_SCANNER = light_scanner.c 
OBJ_LIGHT_SCANNER = light_scanner.o
SRC_NAVIGATION = navigation.c 
OBJ_NAVIGATION = navigation.o
SRC_DRIVER = driver.c 
OBJ_DRIVER = driver.o
SRC_MAIN = main.c 
OBJ_MAIN = main.o

#################################################################
#  Modules (aka, collections of object files).
#
# nb: main.o is *not* included in any modules.
#
MOD_CORE = $(OBJ_HWABSTRACTION) $(OBJ_INPUT_CONTROLLER) \
           $(OBJ_OUTPUT_CONTROLLER)
MOD_NAVIGATION = $(OBJ_2D) $(OBJ_MOTORS) $(OBJ_LIGHT_SCANNER) \
                 $(OBJ_NAVIGATION)
MOD_RUNTIME = $(OBJ_DRIVER)
MOD_ROBOT = $(MOD_CORE) $(MOD_NAVIGATION) $(MOD_RUNTIME)



#################################################################
#
#  Set up compiler and dependency flags depending on what we
#  are trying to build.  .DEFAULT_GOAL is the first target passed
#  into make on the command-line.
#
CDEFS = 
CFLAGS = 
#
#  FIXME
#
#setdeps: 
#	ifeq ($(.DEFAULT_GOAL), mod_core)
#		OBJ_DEPS = $(MOD_CORE)
#        	CDEFS = -DMOD_CORE
#	else
#		ifeq($(.DEFAULT_GOAL), mod_navigation)
#			OBJ_DEPS = $(MOD_NAVIGATION)
#			CDEFS = -DMOD_NAVIGATION
#		else
#			ifeq($(.DEFAULT_GOAL), mod_runtime)
#				OBJ_DEPS = $(MOD_RUNTIME)
#				CDEFS = -DMOD_RUNTIME
#			else
#				OBJ_DEPS = $(MOD_ROBOT)
#				CDEFS = -DMOD_ROBOT
#			endif
#		endif
#	endif

			
	

#################################################################
#
# global compiler and linker options.
INCLUDE = -I$(AVR_HOME)/include -I$(AVR_HOME)/avr/include -I.
LDPATH = -L$(AVR_HOME)/avr/lib -L$(AVR_HOME)/lib64 -L$(AVR_HOME)/lib
LIBS = -lm
OPTIMIZE = -O2
DEBUG = dwarf-2 
CDEFS += -DF_CPU=$(F_CPU)UL -DDEVICETYPE=$(MCU_TARGET)
CFLAGS += -g$(DEBUG) -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) \
           $(INCLUDE)
LDFLAGS = $(LDPATH) $(LIBS) -Wl,-Map,$(PRG_ROBOT).map


#################################################################
#
# First level targets: build the whole robot or an individual module.
# Also, clean target to delete any compiled files for a rebuild.
#
# NB - only compile modules, no linking is done.
all: $(PRG_ROBOT).elf hex eep lss sym 
mod_core: $(MOD_CORE) 
mod_navigation: $(MOD_NAVIGATION)
mod_runtime: $(MOD_RUNTIME)

clean:	
	rm -f *.o *.elf hex eep lss sym



#################################################################
#
# Build the whole robot.  (compile, link and generate extra avr
# files to be loaded onto the microcontroller w/ avrdude.)
#
# make the target called $PRG_ROBOT.elf.  This is the base elf file
# from which other avr files (hex epp lss sym) are created.
$(PRG_ROBOT).elf: $(MOD_ROBOT) $(OBJ_MAIN)
	$(CC) $(CFLAGS) $(CDEFS) $(LDFLAGS) \
	-o $@ $(MOD_ROBOT) $(OBJ_MAIN)

# make extended listing file from the elf.
lss: $(PRG_ROBOT).elf
	$(OBJDUMP) -h -S $< > $@

# make hex final output file from the elf.
hex: $(PRG_ROBOT).elf
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@

# make eeprom file from the elf.
eep: $(PRG_ROBOT).elf
	$(OBJCOPY) -j .eeprom \
	--set-section-flags=.eeprom="alloc,load" \
	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@

# make the symbol file from the elf.
sym: $(PRG_ROBOT).elf
	$(NM) -n $< > $@


#################################################################
#
# compile the main object file.  This only happens if you just
# run 'make' or 'make all'.  This does not happen if you build
# modules individually.
$(OBJ_MAIN): $(SRC_MAIN) 
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

#################################################################
#
# compile the individual mod_core files.
$(OBJ_HWABSTRACTION): $(SRC_HWABSTRACTION) 
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

$(OBJ_INPUT_CONTROLLER): $(SRC_INPUT_CONTROLLER)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

$(OBJ_OUTPUT_CONTROLLER): $(SRC_OUTPUT_CONTROLLER)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

#################################################################
#
# compile the individual mod_navigation files.
$(OBJ_2D): $(SRC_2D)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

$(OBJ_MOTORS): $(SRC_MOTORS)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

$(OBJ_LIGHT_SCANNER): $(SRC_LIGHT_SCANNER)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

$(OBJ_NAVIGATION): $(SRC_NAVIGATION)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^

#################################################################
#
# compile the individual mod_runtime files.
$(OBJ_DRIVER): $(SRC_DRIVER)
	$(CC) $(CFLAGS) $(CDEFS) -c -o $@ $^



